



#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <boost/smart_ptr.hpp>
#include <boost/make_shared.hpp>

using namespace std;

typedef vector<boost::shared_ptr<int>> vs;

void handle_share(vs &v)
{
    int i = 0;
    vs::iterator vIter = v.begin();
    for (; vIter != v.end(); ++vIter)
    {
        (*vIter) = boost::make_shared<int>(++i);
        cout<<*(*vIter)<<", ";
    }
    cout<<endl;

    boost::shared_ptr<int> p = v[9];
    *p = 100;
    cout<<*v[9]<<endl;

    std::cout<<"p use:"<<p.use_count() <<std::endl;


    vIter = v.begin(); int j=0;
    for (; vIter != v.end(); ++vIter)
    {
        j++;
        if(j==7)
        {
            vIter->reset();
        }
    }

}

class frame{

public:
    frame(){}
    ~frame(){}

    int x ;
    int y ;
    int z ;
    int m[1024];
};

typedef  boost::shared_ptr<frame> frame_ptr ;
typedef  boost::weak_ptr<frame> frame_ptr_w ;

int main(int argc, char* argv[])
{
    //创建string的共享指针
    boost::shared_ptr<string> sp = boost::make_shared<string>("hello world");
    //创建vector的共享指针
    boost::shared_ptr<vector<int>> spv =
            boost::make_shared<vector<int>>(10, 2);
    assert(spv->size() == 10);

    cout<<*sp<<endl;
    cout<<(*spv)[0]<<endl;

    //标准容器持有shared_ptr使用

    vs v(10);

    handle_share(v);

    std::cout<<"sp use:"<<sp.use_count() <<std::endl;
    std::cout<<"spv use:"<<spv.use_count() <<std::endl;


    for(auto vs_node: v)
    {
        std::cout<<"vs_node use:"<<vs_node.use_count() << " address: "<<vs_node.get()<<std::endl;

    }

    vs::iterator vIter = v.begin();
    int i=0;
    for (; vIter != v.end(); ++vIter)
    {
        if(vIter->use_count()> 0) {
            cout << "node: "<<i<< "  :"<< *(*vIter) << ", "<<std::endl;
        }
        i++;
    }
    cout<<endl;


    for(auto vs_node: v)
    {
        std::cout<<"vs_node use:"<<vs_node.use_count() <<std::endl;
    }


#if 0
    // 验证 类在 智能指针的使用问题
    {
//        std::map<int,frame_ptr> mp_frame;
        std::map<int,frame_ptr> mp_frame;

        {

            // 这里做元素添加。
            for(int i=0 ;i < 200000 ;i ++)
            {
                frame_ptr kf = boost::make_shared<frame>();
                kf.get()->x =  i;
                kf.get()->y =  i + 5;
                kf.get()->z =  i + 77;
                mp_frame[i] = kf ;
            }

            //这里做reset 智能指针计数
            {
                for(auto kf_node: mp_frame)
                {
//                    std::cout << " id: " << kf_node.first <<" count: "<< kf_node.second.use_count()<<std::endl;
                    kf_node.second.reset();
//                    std::cout << " id: " << kf_node.first <<" count: "<< kf_node.second.use_count()<<std::endl;
                }
            }

            //这里仍然尝试访问. 很明显说明之前的reset是不成功的！！！
            {
                for(auto kf_node: mp_frame)
                {
//                    std::cout << " id: " << kf_node.first <<" address : "<< kf_node.second << " count :" <<kf_node.second.use_count();
//                    std::cout << " x: "<< kf_node.second.get()->x ;
//                    std::cout << " y: "<< kf_node.second.get()->y;
//                    std::cout << " z: "<< kf_node.second.get()->z <<std::endl;;
                    int kkk = kf_node.second.get()->x ;
                }

            }

            std::cout<<"to erase"<<std::endl;
            getchar();
            //现在来试试erase
            {
                int i=0;
                for ( auto iter = mp_frame.begin(); iter != mp_frame.end(); )
                {
//                    i++;
//                    if(i==3)
//                    {
                        iter = mp_frame.erase(iter);
//                    }
//                    iter++;
                }
            }
            std::cout<<"to print"<<std::endl;
            getchar();
            std::cout<<"========================================================================="<<std::endl;
            // erase 完了之后再来试下 妈蛋！ 你会发现，虽然map没有了，但是内存还在！！
            {
                for(auto kf_node: mp_frame)
                {
                    std::cout << " id: " << kf_node.first <<" address : "<< kf_node.second << " count :" <<kf_node.second.use_count();
                    std::cout << " x: "<< kf_node.second.get()->x ;
                    std::cout << " y: "<< kf_node.second.get()->y;
                    std::cout << " z: "<< kf_node.second.get()->z <<std::endl;;
                }

            }

            std::cout<<"to exit?"<<std::endl;
            getchar();
            std::cout<<" exit after 3 secs "<<std::endl;
            sleep(3);
        }
    }

#endif

    //
    {
        std::cout<<"现在开始演示 weak ptr 对此的解决方案 回车后开始"<<std::endl;
        getchar();
        std::map<int,frame_ptr> mp_frame_w;



        // 这里做元素添加。
        for(int i=0 ;i < 200000 ;i ++)
        {
//            frame_ptr kf = boost::make_shared<frame>();
//            kf.get()->x =  i;
//            kf.get()->y =  i + 5;
//            kf.get()->z =  i + 77;
//
////            frame_ptr_w kf_w(kf) ;
//            mp_frame_w[i] = kf ;
            mp_frame_w[i] = boost::make_shared<frame>();
            mp_frame_w[i].get()->x = i ;
            mp_frame_w[i].get()->y = i + 6;
            mp_frame_w[i].get()->z = i + 66;
        }

        std::cout<<"加载完了，先看看内存 然后 回车 to erase weak ptr"<<std::endl;
        //这里仍然尝试访问. 很明显说明之前的reset是不成功的！！！
        {
            for(auto kf_node: mp_frame_w)
            {
                    std::cout << " id: " << kf_node.first <<" address : "<< kf_node.second << " count :" <<kf_node.second.use_count();
                    std::cout << " x: "<< kf_node.second.get()->x ;
                    std::cout << " y: "<< kf_node.second.get()->y;
                    std::cout << " z: "<< kf_node.second.get()->z <<std::endl;;
                int kkk = kf_node.second.get()->x ;
            }

        }
        getchar();
        //现在来试试erase
        {
            int i=0;
            for ( auto iter = mp_frame_w.begin(); iter != mp_frame_w.end(); )
            {
//                    i++;
//                    if(i==3)
//                    {
                iter = mp_frame_w.erase(iter);
//                    }
//                    iter++;
            }
        }
        std::cout<<"to wai to check"<<std::endl;
        getchar();
        std::cout<<"========================================================================="<<std::endl;

        std::cout<<"to exit?"<<std::endl;
        getchar();
        std::cout<<" exit after 3 secs "<<std::endl;
        sleep(3);

    }

    return 0;
}



